#include "LDCGameMain.h"

//-------------------------------------------------------------------------------------
LDCGameMain::LDCGameMain(void)
{
}
//-------------------------------------------------------------------------------------
LDCGameMain::~LDCGameMain(void)
{
}

//-------------------------------------------------------------------------------------
void LDCGameMain::createScene(void)
{
    // Set the scene's ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
	//Create shadows
	mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
    // Create a character Entity
	Ogre::Entity* entNinja = mSceneMgr->createEntity("Ninja","ninja.mesh");
	entNinja->setCastShadows(true);
	mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode")->attachObject(entNinja);
	//Create a simple plane for the entity to stand on
	Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
	//register the plane for use
	Ogre::MeshManager::getSingleton().createPlane("ground",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,
		1500,1500,20,20,true,1,5,5,Ogre::Vector3::UNIT_Z);
	//create an entity from this mesh and place it on the scene
	Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground");
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entGround);
	//Alter texture & cast shadow
	entGround->setMaterialName("Examples/Rockwall");
	entGround->setCastShadows(false);
    // Create a point Light and set its properties
	Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");
	pointLight->setType(Ogre::Light::LT_POINT);
	pointLight->setPosition(Ogre::Vector3(0,150,250));
	pointLight->setDiffuseColour(1.0,0.0,0.0);
	pointLight->setSpecularColour(1.0,0.0,0.0);
	//create a directional light and set its properties
	Ogre::Light* directionalLight = mSceneMgr->createLight("directionalLight");
	directionalLight->setType(Ogre::Light::LT_DIRECTIONAL);
	directionalLight->setDiffuseColour(Ogre::ColourValue(.25,.25,0));
	directionalLight->setSpecularColour(Ogre::ColourValue(.25,.25,0));
	directionalLight->setDirection(Ogre::Vector3(0,-1,-1));
	//create a spotLight and set its properties
	Ogre::Light* spotLight = mSceneMgr->createLight("spotLight");
	spotLight->setType(Ogre::Light::LT_SPOTLIGHT);
	spotLight->setDiffuseColour(0,0,1.0);
	spotLight->setSpecularColour(0,0,1.0);
	spotLight->setDirection(-1,-1,0);
	spotLight->setPosition(Ogre::Vector3(300,300,0));
	spotLight->setSpotlightRange(Ogre::Degree(35), Ogre::Degree(50));
}

void LDCGameMain::createCamera(void)
{
	//create the camera
	mCamera = mSceneMgr->createCamera("PlayerCam");
	//set its position, direction
	mCamera->setPosition(Ogre::Vector3(0,1000,200));
	mCamera->lookAt(Ogre::Vector3(0,0,0));
	//set the near clipping distance
	mCamera->setNearClipDistance(5);
	//create a default camera controller
	mCameraMan = new OgreBites::SdkCameraMan(mCamera);
}

void LDCGameMain::createViewports(void)
{
	//create one viewport, entire window
	Ogre::Viewport* vp = mWindow->addViewport(mCamera);
	//set background color
	vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
	//alter the camera aspect ratio to match the viewport
	mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
}

//update 20131110 ## Add frame Listener

bool LDCGameMain::processUnbufferedInput(const Ogre::FrameEvent& evt)
{
	//static variables
	static bool mMouseDown = false;  //If a mouse button is depressed
	static Ogre::Real mToggle = 0.0;  //The time left until next toggle
	static Ogre::Real mRotate = 0.13;  //The rotate constant
	static Ogre::Real mMove = 250;  //The movement constant
	//true if mouse(LFB) is down
	bool currMouse = mMouse->getMouseState().buttonDown(OIS::MB_Left);
	if(currMouse && !mMouseDown)
	{
		Ogre::Light* light = mSceneMgr->getLight("pointLight");
		light->setVisible(!light->isVisible());
	}
	mMouseDown = currMouse;
	/*mToggle -= evt.timeSinceLastFrame;*/

	//hold the position translated to
	Ogre::Vector3 transVector = Ogre::Vector3::ZERO;
	if(mKeyboard->isKeyDown(OIS::KC_I))     //move forward
	{
		transVector.z -= mMove;
	}
	if(mKeyboard->isKeyDown(OIS::KC_K))
	{
		transVector.z += mMove;
	}
	if(mKeyboard->isKeyDown(OIS::KC_J))
	{
		if(mKeyboard->isKeyDown(OIS::KC_LSHIFT))
		{
			//Yaw left
			mSceneMgr->getSceneNode("NinjaNode")->yaw(Ogre::Degree(mRotate*5));
		}
		else
		{
			transVector.x -= mMove;  //move left
		}
	}
	if(mKeyboard->isKeyDown(OIS::KC_L))
	{
		if(mKeyboard->isKeyDown(OIS::KC_LSHIFT))
		{
			//Yaw right
			mSceneMgr->getSceneNode("NinjaNode")->yaw(Ogre::Degree(-mRotate*5));
		}
		else
		{
			transVector.x += mMove;  //move right
		}
	}

	mSceneMgr->getSceneNode("NinjaNode")->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);

	return true;
}

bool LDCGameMain::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    bool ret = BaseApplication::frameRenderingQueued(evt);
 
    if(!processUnbufferedInput(evt)) return false;
 
    return ret;
}



#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
    int main(int argc, char *argv[])
#endif
    {
        // Create application object
        LDCGameMain app;

        try {
            app.go();
        } catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
            std::cerr << "An exception has occured: " <<
                e.getFullDescription().c_str() << std::endl;
#endif
        }

        return 0;
    }

#ifdef __cplusplus
}
#endif
